#include "dominion.h"
#include "dominion_helpers.h"
#include "sput/sput.h"
#include <stdlib.h>
#include <time.h>

struct gameState *testState;

static void test_card(void)
{
    int *bonus = NULL;

    int card = embargo;

    int choice1;
    int choice2 = -1;
    int choice3 = 1;
    // set to 'curse' if card doesn't take that choice as an argument; otherwise
    // set to 'treasure_map'.
    int choice1_lim = treasure_map;

    int has_supply;
    int supply_count;

    int init_coin_count;
    int init_deck_count;
    int init_embargo_tokens;
    int init_hand_count;
    int init_num_buys;
    int init_played_card_count;
    int init_ops_hand_counts;


    int handPos;
    int player;
    int res;
    int numPlayers;

    int kc[10] = {adventurer, council_room, feast, gardens, mine, remodel,
                  smithy, village, baron, great_hall
                 };

    // iterate through all player counts
    for(numPlayers = 2; numPlayers <= MAX_PLAYERS; numPlayers++) {
        initializeGame(numPlayers, kc, rand(), testState);
        supply_count = 3;

        for(has_supply = 0; has_supply <= 1; has_supply++ ) {
            // iterate though all cards
            for(choice1 = curse; choice1 <= choice1_lim; choice1++) {
                //iterate over players
                for(player = 0; player < testState->numPlayers; player++) {
                    // set turn to current player
                    testState->whoseTurn = player;

                    // place card in current hand position
                    handPos = 0;
                    testState->hand[player][handPos] = card;

                    if(has_supply)
                        testState->supplyCount[choice1] = supply_count;
                    else
                        testState->supplyCount[choice1] = -1;

                    init_hand_count = testState->handCount[player];
                    init_deck_count = testState->deckCount[player];
                    init_coin_count = testState->coins;
                    init_played_card_count = testState->playedCardCount;
                    init_embargo_tokens = testState->embargoTokens[choice1];

                    // set buys to one to initialize turn
                    init_num_buys = testState->numBuys = 1;
                    // other players' hand counts
                    init_ops_hand_counts = ops_hand_counts(player, testState);

                    // play the card
                    res = cardEffect(card, choice1, choice2, choice3, testState, handPos, bonus);

                    /* HERE'S WHERE WE TEST THE CARD'S EFFECT */
                    if(! has_supply)
                        sput_fail_unless(res == -1, "failed to place embargo token on non-existent supply pile");

                    if(res != -1) {
                        sput_fail_if(testState->playedCardCount == init_played_card_count + 1, "trashed card");
                        sput_fail_if(testState->playedCards[testState->playedCardCount - 1] == card, "trashed card");
                        sput_fail_unless(testState->embargoTokens[choice1] == init_embargo_tokens + 1, "added embargo token to pile");
                        sput_fail_unless(testState->coins == init_coin_count + 2, "added 2 coins");
                    }


                    /* END TESTING CARD EFFECT */

                }   /* player */
            }   /* choice1 */
        }   /* has_supply */
    }   /* numPlayers */
}

int main(int argc, char *argv[])
{
    // Seed random number generator
    srand(time(NULL));

    // Initialize game state
    testState = newGame();

    sput_start_testing();
    sput_enter_suite(__FILE__);

    sput_run_test(test_card);
    sput_finish_testing();

    free(testState);

    return sput_get_return_value();
}
